#include <cstdio>
#include <stdint.h>
#include "mapa.h"

Mapa::Mapa()
{
    numNiveis = 0;
}

Mapa::~Mapa()
{
	/*mata tudo*/
    for (int i=0 ; i<numNiveis ; ++i)
    {
		for (int j=0 ; j<DIMENSAO ; ++j)
			delete mapas[i][j];
        delete mapas[i];
    }
    delete mapas;
}

bool Mapa::carrega(const char *arquivo)
{
	FILE *arq;

	arq = fopen(arquivo, "r");
	if (!arq)
	{
		perror("Não foi possível abrir o arquivo");
		return false;
	}

	/*a linha tem que aguentar os 30 caracteres e o \0*/
	uint8_t linha[DIMENSAO+1];
	int a;
	/*lê a quantidade de níveis*/
	fscanf(arq,"%i\n",&a);
	numNiveis = a;
	/*aloca espaço pra todos os níveis*/
	aloca(numNiveis);

	for (int i=0 ; i<numNiveis ; ++i)
	{
		for (int j=0 ; j<DIMENSAO ; ++j)
		{
			/*lê cada linha*/
			fscanf(arq, "%31s", linha);
			for (int k=0 ; k<DIMENSAO ; ++k)
			{
				/*checa se o caracter do arquivo é válido e tal*/
				/*também faz as coisas certas de colocar 1 onde tem parede*/
				switch (linha[k])
				{
				    case '#':
						mapas[i][j][k] = 1;
						break;
					case '.':
						mapas[i][j][k] = 0;
						break;
					case '$':
						mapas[i][j][k] = 0;
						inicio[0] = j;
						inicio[1] = k;
						inicio[2] = i;
						break;
					case '%':
						mapas[i][j][k] = 0;
						fim[0] = j;
						fim[1] = k;
						fim[2] = i;
						break;
					default:
						printf(
						"TAPADO!! APRENDE A USAR ISSO DIREITO!!\n"
						"Só por isso, vai dar pau no jogo ;)\n"
						"Coisa estranha: %c\n", linha[k]);
						break;
				}
			}
		}
	}
	fclose(arq);
	return true;
}

bool Mapa::aloca(int quantidade)
{
	/*aloca um vetor de matrizes (YEAH!)*/
	mapas = new uint8_t**[quantidade];
	for (int i=0 ; i<quantidade ; ++i)
	{
		/*linhas pra cada uma das matrizes (ou colunas?)*/
		mapas[i] = new uint8_t*[DIMENSAO];
		for (int j=0 ; j<DIMENSAO ; ++j)
		{
			/*células de cada uma das matrizes*/
			mapas[i][j] = new uint8_t[DIMENSAO];
		}
	}
	return true;
}

/*  FIXME: arrumar isso aqui
*   To deixando o usuário destruir tudo se quiser*/
/*ah, facilidades do mundo moderno.*/
uint8_t& Mapa::operator()(int mapa, int x, int y)
{
	return mapas[mapa][x][y];
}

